import 'dart:convert';

import 'package:equatable/equatable.dart';

class Channel extends Equatable {
  final int? id;
  final String? name;
  final String? url;
  final String? thumbnailUrl;
  final Capabilities? capabilities;

  const Channel({
    this.id,
    this.name,
    this.url,
    this.thumbnailUrl,
    this.capabilities,
  });

  factory Channel.fromMap(Map<String, dynamic> data) => Channel(
        id: data['id'] as int?,
        name: data['name'] as String?,
        url: data['url'] as String?,
        thumbnailUrl: data['thumbnailUrl'] as String?,
        capabilities: data['capabilities'] != null
            ? Capabilities.fromMap(data['capabilities'] as Map<String, dynamic>)
            : null,
      );

  Map<String, dynamic> toMap() => {
        'id': id,
        'name': name,
        'url': url,
        'thumbnailUrl': thumbnailUrl,
        'capabilities': capabilities?.toMap(),
      };

  /// `dart:convert`
  ///
  /// Parses the string and returns the resulting Json object as [Channel].
  factory Channel.fromJson(String data) {
    return Channel.fromMap(json.decode(data) as Map<String, dynamic>);
  }

  /// `dart:convert`
  ///
  /// Converts [Channel] to a JSON string.
  String toJson() => json.encode(toMap());

  Channel copyWith({
    int? id,
    String? name,
    String? url,
    String? thumbnailUrl,
    Capabilities? capabilities,
  }) {
    return Channel(
      id: id ?? this.id,
      name: name ?? this.name,
      url: url ?? this.url,
      thumbnailUrl: thumbnailUrl ?? this.thumbnailUrl,
      capabilities: capabilities ?? this.capabilities,
    );
  }

  @override
  bool get stringify => true;

  @override
  List<Object?> get props => [id, name, url, thumbnailUrl, capabilities];
}

class Capabilities extends Equatable {
  final bool? twoWayAudio;
  final bool? ptzControl;

  const Capabilities({
    this.twoWayAudio,
    this.ptzControl,
  });

  factory Capabilities.fromMap(Map<String, dynamic> data) => Capabilities(
        twoWayAudio: data['twoWayAudio'] as bool? ?? false,
        ptzControl: data['ptzControl'] as bool? ?? false,
      );

  Map<String, dynamic> toMap() => {
        'twoWayAudio': twoWayAudio,
        'ptzControl': ptzControl,
      };

  Capabilities copyWith({
    bool? twoWayAudio,
    bool? ptzControl,
  }) {
    return Capabilities(
      twoWayAudio: twoWayAudio ?? this.twoWayAudio,
      ptzControl: ptzControl ?? this.ptzControl,
    );
  }

  @override
  bool get stringify => true;

  @override
  List<Object?> get props => [twoWayAudio, ptzControl];
}
